home *** CD-ROM | disk | FTP | other *** search
- # include <ingres.h>
- # include <aux.h>
- # include <symbol.h>
- # include <tree.h>
- # include "qrymod.h"
-
- /*
- ** TRIMQLEND -- trim QLEND node off of qualification
- **
- ** The QLEND node, and possible the AND node preceeding it,
- ** are trimmed off. The result of this routine should be
- ** a very ordinary tree like you might see in some textbook.
- **
- ** A fast not on the algorithm: the pointer 't' points to the
- ** current node (the one which we are checking for a QLEND).
- ** 's' points to 't's parent, and 'r' points to 's's parent;
- ** 'r' is NULL at the top of the tree.
- **
- ** This routine works correctly on trees with no QLEND in
- ** the first place, returning the original tree.
- **
- ** If there is a QLEND, it must be on the far right branch
- ** of the tree, that is, the tree must be INGRES-canonical.
- **
- ** Parameters:
- ** qual -- the qualification to be trimmed.
- **
- ** Returns:
- ** A pointer to the new qualification.
- ** NULL if the qualification was null once the
- ** QLEND is stripped.
- **
- ** Side Effects:
- ** The tree pointed to by 'qual' may be modified.
- **
- ** Trace Flags:
- ** none
- */
-
- QTREE *
- trimqlend(qual)
- QTREE *qual;
- {
- register QTREE *t;
- register QTREE *s;
- register QTREE *r;
-
- t = qual;
-
- /* check for the simple null qualification case */
- if (t == NULL || t->sym.type == QLEND)
- return (NULL);
-
- /* scan tree for QLEND node */
- for (r = NULL, s = t; (t = t->right) != NULL; r = s, s = t)
- {
- if (t->sym.type == QLEND)
- {
- /* trim of QLEND and AND node */
- if (r == NULL)
- {
- /* only one AND -- return its operand */
- return (s->left);
- }
-
- r->right = s->left;
- break;
- }
- }
-
- /* return tree with final AND node and QLEND node pruned */
- return (qual);
- }
- /*
- ** APPQUAL -- append qualification to tree
- **
- ** The qualification is conjoined to the qualificaion of the
- ** tree which is passed.
- **
- ** Parameters:
- ** qual -- a pointer to the qualification to be appended.
- ** root -- a pointer to the tree to be appended to.
- **
- ** Returns:
- ** none
- **
- ** Side Effects:
- ** Both 'qual' ad 'root' may be modified. Note that
- ** 'qual' is linked into 'root', and must be
- ** retained.
- **
- ** Trace Flags:
- ** 13
- */
-
- appqual(qual, root)
- QTREE *qual;
- QTREE *root;
- {
- register QTREE *p;
- register QTREE *r;
-
- r = root;
- # ifdef xQTR3
- if (r == NULL)
- syserr("appqual: NULL root");
- # endif
-
- /*
- ** Find node before QLEND node
- ** p points the node we are examining, r points to
- ** it's parent.
- */
-
- while ((p = r->right) != NULL && p->sym.type != QLEND)
- {
- # ifdef xQTR3
- if (p->sym.type != AND)
- syserr("appqual: node %d", p->sym.type);
- # endif
- r = p;
- }
-
- /* link in qualification */
- r->right = qual;
- }
- /*
- ** QMERROR -- issue fatal error message and abort query
- **
- ** This call is almost exactly like 'error' (which is called),
- ** but never returns: the return is done by 'reset'. Also, the
- ** R_up pipe is flushed.
- **
- ** Parameters:
- ** errno -- the error number.
- ** qmode -- the query mode to pass as $0, -1 if none.
- ** vn -- the varno of the relation name to pass as
- ** $1, -1 if none.
- ** p1 to p5 -- the parameters $2 through $6
- **
- ** Returns:
- ** non-local (via reset())
- **
- ** Side Effects:
- ** The error message is generated.
- **
- ** Trace Flags:
- ** none
- */
-
- char *QmdName[] =
- {
- "[ERROR]", /* 0 = mdRETTERM */
- "RETRIEVE", /* 1 = mdRETR */
- "APPEND", /* 2 = mdAPP */
- "REPLACE", /* 3 = mdREPL */
- "DELETE", /* 4 = mdDEL */
- "", /* 5 = mdCOPY */
- "", /* 6 = mdCREATE */
- "", /* 7 = mdDESTROY */
- "", /* 8 = mdHELP */
- "", /* 9 = mdINDEX */
- "", /* 10 = mdMODIFY */
- "", /* 11 = mdPRINT */
- "", /* 12 = mdRANGE */
- "", /* 13 = mdSAVE */
- "DEFINE", /* 14 = mdDEFINE */
- "RET_UNIQUE", /* 15 = mdRET_UNI */
- "", /* 16 = mdVIEW */
- "", /* 17 = mdUPDATE */
- "", /* 18 = mdRESETREL */
- "", /* 19 = mdERIC */
- "", /* 20 = mdNETQRY */
- "", /* 21 = mdMOVEREL */
- "", /* 22 = mdPROT */
- "", /* 23 = mdINTEG */
- "", /* 24 = mdDCREATE */
- };
-
-
- qmerror(errno, qmode, vn, p1, p2, p3, p4, p5, p6)
- int errno;
- int qmode;
- int vn;
- char *p1, *p2, *p3, *p4, *p5, *p6;
- {
- register char *x1;
- register char *x2;
- char xbuf[MAXNAME + 1];
- register int i;
- extern char *trim_relname();
-
- /* set up qmode and varno parameters */
- x1 = x2 = "";
- i = qmode;
- if (i >= 0)
- x1 = QmdName[i];
- i = vn;
- if (i >= 0)
- smove(trim_relname(Qt.qt_rangev[i].rngvdesc->reldum.relid),
- x2 = xbuf);
-
- /* issue the error message and exit */
- error(errno, x1, x2, p1, p2, p3, p4, p5, p6, 0);
- syserr("qmerror");
- }
- /*
- ** LSETBIT -- set a bit in a domain set
- **
- ** Parameters:
- ** bitno -- the bit number to set (0 -> 127)
- ** xset -- the set to set it in.
- **
- ** Returns:
- ** none
- **
- ** Side Effects:
- ** none
- */
-
- lsetbit(bitno, xset)
- int bitno;
- long xset[4];
- {
- register int b;
- register int n;
- register int *x;
-
- x = xset;
-
- b = bitno;
- n = b >> LOG2WORDSIZE;
- b &= WORDSIZE - 1;
-
- x[n] |= 1 << b;
- }
- /*
- ** MERGEVAR -- merge variable numbers to link terms
- **
- ** One specified variable gets mapped into another, effectively
- ** merging those two variables. This is used for protection
- ** and integrity, since the constraint read from the tree
- ** must coincide with one of the variables in the query tree.
- **
- ** Parameters:
- ** va -- the variable which will dissappear.
- ** vb -- the variable which 'va' gets mapped into.
- ** root -- the root of the tree to map.
- **
- ** Returns:
- ** none
- **
- ** Side Effects:
- ** The tree pointed at by 'root' gets VAR and RESDOM
- ** nodes mapped.
- ** Range table entry for 'va' is deallocated.
- ** The 'Qt.qt_remap' vector gets reset and left in an
- ** undefined state.
- **
- ** Trace Flags:
- ** 72
- */
-
- mergevar(a, b, root)
- register int a;
- register int b;
- QTREE *root;
- {
- register int i;
-
- # ifdef xQTR1
- if (tTf(72, 0))
- {
- printf("\nmergevar(%d->%d)", a, b);
- treepr(root);
- }
- # endif
-
- /*
- ** Insure that 'a' and 'b' are consistant, that is,
- ** that they both are in range, are defined, and range over
- ** the same relation.
- */
-
- if (a < 0 || b < 0 || a >= MAXVAR + 1 || b >= MAXVAR + 1)
- syserr("mergevar: range %d %d", a, b);
- if (Qt.qt_rangev[a].rngvdesc == NULL || Qt.qt_rangev[b].rngvdesc == NULL)
- syserr("mergevar: undef %d %d", a, b);
- if (!bequal(Qt.qt_rangev[a].rngvdesc->reldum.relid,
- Qt.qt_rangev[b].rngvdesc->reldum.relid, MAXNAME) ||
- !bequal(Qt.qt_rangev[a].rngvdesc->reldum.relowner,
- Qt.qt_rangev[b].rngvdesc->reldum.relowner, 2))
- {
- syserr("mergevar: incon %.14s %.14s",
- Qt.qt_rangev[a].rngvdesc->reldum.relid,
- Qt.qt_rangev[b].rngvdesc->reldum.relid);
- }
-
- /*
- ** To do the actual mapping, we will set up 'Qt.qt_remap' and
- ** call 'mapvars()'. This is because I am too lazy to
- ** do it myself.
- */
-
- for (i = 0; i < MAXRANGE; i++)
- Qt.qt_remap[i] = i;
- Qt.qt_remap[a] = b;
- mapvars(root);
-
- /* delete a from the range table */
- declare(a, NULL);
- }
- /*
- ** MAKEZERO -- make a node with value 'zero'
- **
- ** A node is created with value representing the zero value
- ** for the specified type, that is, 0 for integers, 0.0 for
- ** floats, and the blank string for chars.
- **
- ** Parameters:
- ** typ -- the node type.
- **
- ** Returns:
- ** a pointer to the zero node.
- **
- ** Side Effects:
- ** space is grabbed from Qbuf
- */
-
- QTREE *
- makezero(typ)
- int typ;
- {
- register int l;
- register QTREE *s;
- int symbuf[(sizeof *s) / sizeof l]; /*word aligned*/
- extern char *need();
-
- s = (QTREE *) symbuf;
- s->sym.type = typ;
-
- switch (typ)
- {
- case INT:
- s->sym.len = l = 2;
- s->sym.value.sym_data.i2type = 0;
- break;
-
- case FLOAT:
- s->sym.len = l = 4;
- s->sym.value.sym_data.f4type = 0.0;
- break;
-
- case CHAR:
- s->sym.len = l = 2;
- s->sym.value.sym_data.i2type = ' '; /* (two spaces) */
- break;
-
- default:
- syserr("makezero: typ %d", typ);
- }
-
- /* duplicate the node into Qbuf */
- l += 2 + 2 * QT_HDR_SIZ; /* size of type + len + left + right */
- s = (QTREE *) need(Qbuf, l);
- bmove(symbuf, s, l);
- return (s);
- }
-